import uuid
from typing import List, Optional

from server.app.cloud_ide.schema.tenant.request.tenant_create_request import TenantCreateRequest
from server.app.cloud_ide.schema.tenant.request.tenant_update_request import TenantUpdateRequest
from server.app.cloud_ide.schema.tenant.response.tenant_list_entity import TenantListEntity
from server.app.cloud_ide.schema.tenant.response.tenent_info_response import TenantInfoResponse
from server.framework.core.logger import logger
from server.framework.utils.keycloak_manager import build_keycloak_admin
from server.framework.utils.kubernetes.kubernetes_client import KubernetesClient


class TenantService:
    def get_all_tenants(self):
        keycloak_admin = build_keycloak_admin()
        tenants = keycloak_admin.get_groups()
        return tenants

    def list_tenant(self) -> List[TenantListEntity]:
        """
        获取租户列表
        @return:
        """
        keycloak_admin = build_keycloak_admin()
        groups = keycloak_admin.get_groups()

        results = []
        for group in groups:
            group_details = keycloak_admin.get_group(group['id'])
            if 'max_cpu' in group_details['attributes']:
                max_cpu = int(group_details['attributes']['max_cpu'][0])
            else:
                max_cpu = 0

            if 'max_memory' in group_details['attributes']:
                max_memory = int(group_details['attributes']['max_memory'][0])
            else:
                max_memory = 0

            if 'max_disk' in group_details['attributes']:
                max_disk = int(group_details['attributes']['max_disk'][0])
            else:
                max_disk = 0

            if 'allow_nodes' in group_details['attributes']:
                allow_nodes = str(group_details['attributes']['allow_nodes'][0])
            else:
                allow_nodes = ''

            results.append(TenantListEntity(
                id=group_details['id'],
                name=group_details['name'],
                max_cpu=max_cpu,
                max_memory=max_memory,
                max_disk=max_disk,
                allow_nodes=allow_nodes
            ))
        return results

    def delete_tenant(self, ids: list) -> bool:
        try:
            keycloak_admin = build_keycloak_admin()
            kubernetes_manager = KubernetesClient()
            for id in ids:
                group_details = keycloak_admin.get_group(group_id=id)
                kubernetes_manager.delete_namespace(group_details['attributes']['namespace'][0])
                keycloak_admin.delete_group(group_id=id)
            return True
        except Exception as e:
            logger.error(f'删除租户[{ids}]失败,异常信息:[{e}]')
            return False

    def update_tenant(self, data: TenantUpdateRequest):
        try:
            keycloak_admin = build_keycloak_admin()
            group_details = keycloak_admin.get_group(data.id)

            payload = {
                'name': data.name,
                'path': f'/{data.name}',
                'realmRoles': [],
                'clientRoles': {},
                'subGroups': [],
                'attributes': {
                    'max_cpu': [data.max_cpu],
                    'max_disk': [data.max_disk],
                    'allow_nodes': [data.allow_nodes],
                    'max_memory': [data.max_memory],
                    'namespace': [group_details['attributes']['namespace'][0]]
                }
            }
            keycloak_admin.update_group(group_id=data.id, payload=payload)

            kubernetes_manager = KubernetesClient()
            kubernetes_manager.edit_namespace_quota(group_details['attributes']['namespace'][0],
                                                    data.max_cpu, data.max_memory,
                                                    data.max_disk)
            return True
        except Exception as e:
            logger.error(f'编辑租户[{data.name}]失败,异常信息:[{e}]')
            return False

    def create_tenant(self, data: TenantCreateRequest):
        """
        创建租户
        @param data:
        @return:
        """
        try:
            namespace = str(uuid.uuid4()).split('-')[0]
            payload = {
                'name': data.name,
                'path': f'/{data.name}',
                'realmRoles': [],
                'clientRoles': {},
                'subGroups': [],
                'attributes': {
                    'max_cpu': [data.max_cpu],
                    'max_disk': [data.max_disk],
                    'allow_nodes': [data.allow_nodes],
                    'max_memory': [data.max_memory],
                    'namespace': [namespace]
                }
            }

            keycloak_admin = build_keycloak_admin()
            keycloak_admin.create_group(payload=payload)

            kubernetes_manager = KubernetesClient()
            kubernetes_manager.create_namespace(namespace)
            kubernetes_manager.create_namespace_quota(namespace, data.max_cpu,
                                                      data.max_memory,
                                                      data.max_disk)
            return True
        except Exception as e:
            logger.error(f'创建租户[{data.name}]失败,异常原因:[{e}]')
            return False

    def get_tenant_by_name(self, tenant_name):
        tenants = self.list_tenant()
        target = next((x for x in tenants if x.name == tenant_name), None)
        return target

    def get_tenant_info(self, tenant_id: str) -> Optional[TenantInfoResponse]:
        try:
            keycloak_admin = build_keycloak_admin()
            group_details = keycloak_admin.get_group(tenant_id)

            entity = TenantInfoResponse(
                id=tenant_id,
                namespace=group_details['attributes']['namespace'][0],
                name=group_details['name'],
                max_cpu=group_details['attributes']['max_cpu'][0],
                max_memory=group_details['attributes']['max_memory'][0],
                max_disk=group_details['attributes']['max_disk'][0],
                allow_nodes=group_details['attributes']['allow_nodes'][0],
            )
            return entity
        except Exception as e:
            return None
